<template>
  <div v-if="source" class="OctopusTree">
    <div class="Content">
      <!-- <el-button @click="setCheckedKeys">通过 key 设置</el-button> -->
      <transition name="fade">
        <fieldset>
          <legend>{{source.title}}</legend>
          <div class="SearchPanel" v-if="tree_show_filter">
            <el-input placeholder="输入关键字进行过滤" v-model="tree_filter_text"></el-input>
          </div>
          <!--                    {{tree_data}}-->
          <!--                    height: <input type="text" />-->
          <!--                    weight: <input type="text" />-->
          <template v-if="source.data.primaryKey">
            <el-tree :data="tree_data" :show-checkbox="tree_show_checkbox" default-expand-all
                     :node-key="source.data.primaryKey" :expand-on-click-node="tree_auto_expand"
                     ref="tree" @node-click="checkNode" :filter-node-method="filterNode"
                     highlight-current :props="defaultProps" @check-change="checkChange" @check="check"
                     v-bind:style="{height:source.data.height,width:source.data.width}">
            <span class="Node" slot-scope="{ node, data }">
              <slot name="content" :row="{package:node,node:data}"></slot>
              <!-- <span>{{ node.data }}</span> -->
              <!-- <el-button type="text" size="mini" @click="() => append(node,data)">Append</el-button>-->
            </span>
            </el-tree>
          </template>
        </fieldset>
      </transition>
    </div>
  </div>
  <div v-else>Octopus Framework Initialization Exception.</div>
</template>

<script>
  export default {
    name: 'DialogEngine', /* 这个name暂时不知道用啥用，根据官方文档说的是方便排错的 */
    data() {
      return {
        octopus: this.$parent.octopus,
        tree_data: [],              // 保存格式化整理以后的树数据
        tree_filter_key: "",
        tree_filter_text: "",
        tree_show_root: false,      // 是否显示根，默认不显示。
        tree_show_checkbox: true,   // 是否启用复选框
        tree_show_filter: false,    //
        tree_auto_expand: true,     // 点击节点自动伸缩。
        // tree_check_data: [150, 6],          // 保存格式化整理以后的树数据
        defaultProps: {
          children: 'children',
          label: 'label',
        }
      }
    },
    created: function () {
      this.init();
      this.octopus.tips.debug("TreeEngine执行了created事件。");
    },
    mounted: function () {
      this.octopus.tips.debug("TreeEngine执行了mounted事件。");
    },
    activated: function () {
      this.load();
      this.octopus.tips.debug("TreeEngine执行了activated事件。");
    },
    deactivated: function () {
      this.octopus.tips.debug("TreeEngine执行了deactivated事件。");
    },
    destroyed() {
    },
    computed: {
      // 可参考标准List控件。
    },
    methods: {
      init: function () {
        this.initData();
      },
      // 初始化数据
      initData: function () {
        this.source.control = this;

        // 设置显示参数
        if (this.source.show) {
          // 是否显示复选框
          if (this.source.show.checkbox != null) {
            this.tree_show_checkbox = this.source.show.checkbox;
          }
          // 是否显示根
          if (this.source.show.root != null) {
            this.tree_show_root = this.source.show.root;
          }
          // 是否显示搜索
          if (this.source.show.filter != null && this.source.show.filter == true && this.source.filterKey != null) {
            this.tree_show_filter = this.source.show.filter;
            this.tree_filter_key = this.source.filterKey;
          }
        }

        // 设置自动参数
        if (this.source.auto) {
          // 节点自动伸缩
          if (this.source.auto.expand != null) {
            this.tree_auto_expand = this.source.auto.expand;
          }
        }
      },
      // 加载数据
      load: function () {

        // 满足要求才执行查询
        if (this.source.data.id && this.source.data.cellData) {
          let o = this;
          // 替换层级值（如果有）
          this.source.data.parentValue = this.octopus.tools.parseScript(this.source.data.parentValue);
          // 循环处理转义相关八抓鱼代码
          $(this.source.data.cellData).each(function (index, item) {
            if (item.filterValue) {
              // 只有非范围控件支持绑定关联，所以这里只要判断filterValue下标0的数据即可。
              item.filterValue[0] = o.octopus.tools.parseScript(item.filterValue[0]);
              // console.log("======" + JSON.stringify(item));
            }
          });

          // alert(this.octopus.passport.authorization.company);
          // 请求后台八爪鱼API框架，为了节约流量，所以不把queryData大型包再发回去。
          this.octopus.request.api.post("/Octopus/Engine/List", {
              id: o.source.data.id,
              // 如果八爪鱼后台没有配置，则可通过此处的配置来告诉八爪鱼，父级ID是通过这个字段来实现。
              parentKey: this.source.data.parentKey,
              // TODO：虽然传了parentKey和parentValue，但是此处不用，因为树级是由前端完成排序。
              // parentValue: this.source.data.parentValue,
              orderData: o.source.data.orderData,
              cellData: o.source.data.cellData,
              pageData: {rowSize: 9999},  // TODO 赶时间，先加载9999，后续可循环分页加载。
              // pageData: this.source.data.pageData,
              width: this.source.data.width,
              height: this.source.data.height,
              minHeight: this.source.data.minHeight,
              offsetHeight: this.source.data.offsetHeight,
              paramData: this.source.data.paramData,
            },
            // 处理回调事件，通过分析data.status.code的状态来实现。
            function (return_data) {
              if (return_data.status.code == 200) {
                // 加载之前，需要注意的是此时数据并不完整，只是刚从后台获取到。
                // if (o.loadBefore) {
                //   o.loadBefore(return_data);
                // }
                // 打印log
                // console.error(return_data.content);

                // TODO 后续可扩展树控件，对不同控件进行格式化的自动处理。
                // $(data.content.cellData).each(function (index, cell) {
                //   // 如果是多行文本框、标签框、富文本框，则修改为文本框，否则查询组件无法查询哈。
                //   if (cell.controlTypeID == 2 || cell.controlTypeID == 4 || cell.controlTypeID == 18) {
                //     cell.controlTypeID = 1;
                //   }
                //   // 如果是日历时间框，则改为日历框，否则查询不太友好。
                //   else if (cell.controlTypeID == 6) {
                //     cell.controlTypeID = 5;
                //   }
                // });

                // 二次进入时有数据则只更新cellData, queryData,pageData部分。
                // if (return_data.queryData) {
                //   o.$set(o.source.data, "cellData", return_data.content.cellData);
                //   o.$set(o.source.data, "queryData", return_data.content.queryData);
                //   // o.$set(o.source.data, "pageData", data.content.pageData); // TODO 后期转分页动态读取时考虑是否开放
                // }
                // // 首次加载，进行全量更新。
                // else {
                //   // 新增属性，需要使用$set，详细参考：https://blog.csdn.net/panyang01/article/details/76665448
                //   o.$set(o.source, "data", return_data.content);
                // }

                // alert(o.source.data.height);
                // 只更新【列数据】和【数据集】。
                o.$set(o.source.data, "height", return_data.content.height);
                o.$set(o.source.data, "cellData", return_data.content.cellData);
                o.$set(o.source.data, "queryData", return_data.content.queryData);
                // 设置主键盘，设置node-key，
                o.source.data.primaryKey = return_data.content.primaryKey;

                // 执行树结构渲染。
                let base_tree_data = o.getTreeData(o.source.data.parentValue, return_data.content);

                // 显示根
                if (o.tree_show_root) {
                  let rootNodeList = return_data.content.queryData.filter(item => {
                    return item[o.source.data.primaryKey] == o.source.data.parentValue;
                  });
                  // 如果找到根节点
                  if (rootNodeList.length == 1) {
                    let rootNode = rootNodeList[0];
                    // 配置节点。
                    rootNode.children = base_tree_data;
                    o.tree_data = [rootNode];
                  }
                }
                // 不显示根
                else {
                  o.tree_data = base_tree_data;
                }


                if (o.loaded) {
                  // 因为node-key设置为异步了，所以加载需要时间，给 dom 渲染预留时间。
                  setTimeout(function () {
                    // 将整理后的树状数据返回
                    o.loaded(o.tree_data);
                  }, 300);
                }

                // alert(o.source.data.height);
                if (o.source.data.height == "auto") {
                  o.resize();
                  window.onresize = function () {
                    o.resize();
                  }
                }

              } else {
                o.octopus.tips.error(return_data);
              }


              // 初始化link数据
              // o.loadLinkData();
            });
        }
      },
      // 获取树状数据
      getTreeData: function (parentValue, data) {
        let o = this;
        let tree = [];
        // 循环采集数据
        data.queryData.map(row => {
          // 如果等于
          if (row[data.parentKey] == parentValue) {
            // console.error(JSON.stringify(row));
            // 过滤
            let treeNode = tree.filter(item => {
              return item[data.primaryKey] == row[data.primaryKey];
            });

            // 得到节点
            let now_tree_node = null;
            // 如果找到节点
            if (treeNode.length == 1) {
              now_tree_node = treeNode[0];
            }
            // 如果没有找到，则追加
            else {
              now_tree_node = row;
              // 取消该字段。
              // now_tree_node.label = row[o.source.data.KeyName];
              // now_tree_node = {
              //   id: row[o.source.data.KeyValue],
              //   label: row[o.source.data.KeyName],
              //   typeID: row.IDCode,
              // };
              tree.push(now_tree_node);
            }
            // 子系统获取
            now_tree_node.children = o.getTreeData(row[data.primaryKey], data);
            // 插入节点
          }
          // 如果不是父级对应的ID，则不引入。
          else {
            // console.warn(JSON.stringify(row));
          }
        });

        return tree;
      },
      // 搜索节点
      filterNode(value, data) {
        // console.log("filter: " + value);
        // console.log("filter: " + JSON.stringify(data));
        if (!value) {
          return true;
        } else {
          let returnData = data[this.tree_filter_key].indexOf(value) !== -1;
          return returnData;
        }
      },
      // 选中节点
      checkNode: function (data) {
        // console.error(JSON.stringify(data));
        if (this.clicked) {
          this.clicked(data);
        }
      },
      // 1：该节点所对应的对象；2：节点本身是否被选中；3：节点的子树中是否有被选中的节点
      checkChange: function (data, checked, tree) {
        // 选中的，否则这个事件会把所有选中的都给传过来。
        // if (checked) {
        //   // data.children = null;
        //   // this.$refs.tree.setCheckedNodes([data]);
        //   console.error(JSON.stringify(data));
        // }

        console.warn("== checkChange Start ==");
        console.warn(JSON.stringify(data));
        console.warn(JSON.stringify(checked));
        console.warn(JSON.stringify(tree));
      },
      // 选中的节点、半选中的节点
      check: function (currentNode, checkedNodes) {
        // console.error("==check==");
        // console.error(JSON.stringify(currentNode));   // 当前选中的节点对象
        // console.error(JSON.stringify(checkedNodes));  // 已经选中的节点对象、半选中的节点对象

        // this.tree_source = checkedNodes.checkedNodes;
        // 如果有回掉事件。
        if (this.checked) {
          this.checked(checkedNodes);
        }

      },
      // 设置选中的值
      setCheckedKeys: function (data) {
        // this.$refs.tree.setCheckedNodes([150]);
        // this.$refs.tree.setCheckedKeys(["C_194", "C_215"]);
        this.$refs.tree.setCheckedKeys(data);
      },
      // 设置选中的节点
      setCurrentKey: function (data) {
        // this.$refs.tree.setCheckedNodes([150]);
        // this.$refs.tree.setCheckedKeys(["C_194", "C_215"]);
        // alert(data);
        this.$refs.tree.setCurrentKey(data);
      },
      // 获取当前选中的节点
      getCurrentNode:function(){
        // 如果有回掉事件。
        let currentData =  this.$refs.tree.getCurrentNode();
        return currentData;
      },
      append: function (node, data) {
        console.warn(node);
        console.warn(JSON.stringify(data));
      },
      resize: function () {
        let o = this;
        $(document).ready(function () {
          // 延迟0.5秒加载高度
          setHeight();

          // 启动高度设定
          function setHeight() {
            // 设置控件高度
            let controlHeight = 0;
            //o.control_height = 0;
            setTimeout(function () {
              // 下列算法当有研发在list控件外层包了浮动以后，会导致异常，因为浮动以后，文档高度（ $(document.body).height()）就为0了。
              // let list_height = $(window).height() - $(document.body).height();
              // 列表高度 = 可视区高度 - 文档高度（上面高度已经设置位0，所以文档高度正常情况都是小于可视区高度的）
              let list_height = $(window).height() - 27;

              // 如果开启了过滤功能
              if (o.source.show && o.source.show.filter == true) {
                list_height = list_height - 50;
              }

              // 列表高度 大于 0 才有设置的意义，否则太小，出滚动条。
              if (list_height > 0) {

                controlHeight = list_height;
                // 偏移量情况下的高度自适应。
                if (o.source.data.offsetHeight) {
                  controlHeight = controlHeight - o.source.data.offsetHeight;
                }
                // 最小高度限定。
                if (o.source.data.minHeight) {
                  controlHeight = controlHeight < o.source.data.minHeight ? o.source.data.minHeight : controlHeight;
                }

                o.source.data.height = controlHeight + "px";
                // o.source.data.width = ($(o.$refs.tree.$el).width() - 100) + "px";
                // o.source.data.width = "290px";
              }
              // alert(o.source.data.height + "|" + o.source.data.minHeight + "|" + o.source.data.offsetHeight);
              console.log("设置高度：" + o.source.data.height + "，窗体高度：" + $(window).height() + "，测试高度：");
              // console.log($(o.$refs.tree.$el).width());
              // console.log("doc hei:" + $(document).outerHeight() + ", 可视区高度：" + $(window).height()
              //   + ", 文档高度：" + $(document.body).height() + ", " + "分页高度：" + $(".Page").outerHeight());
            }, 500);
          }
        });
      }
    },
    watch: {
      // 可参考标准List控件。
      tree_filter_text(val) {
        // console.log("watch: " + val);
        this.$refs.tree.filter(val);
      }
    },
    // 数据源、加载后、选中后、改变后。
    props: ["source", "loaded", "checked", "changed", "clicked"]
  }
</script>

/*  scoped的意思是这里的样式只对当前页面有效不会影响其他页面，还有可以设置lang="scss"就是支持css预编译，也就是支持sass或者less  */
<!-- Add "scoped" attribute to limit CSS to this component only -->
<style scoped>
  h1, h2 {
    font-weight: normal;
  }
</style>
